////////////////////////////////////////////////////////////////////////////////
/// @file    main.c
/// @author  AE TEAM
/// @brief   THIS FILE PROVIDES ALL THE SYSTEM FUNCTIONS.
////////////////////////////////////////////////////////////////////////////////
/// @attention
///
/// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
/// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
/// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
/// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
/// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
/// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
///
/// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
////////////////////////////////////////////////////////////////////////////////

// Define to prevent recursive inclusion
#define _MAIN_C_

// Files includes
#include "main.h"
#include <lwip/opt.h>
#include <lwip/arch.h>
#include "tcpip.h"
#include "reg_rcc.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "ethernetif.h"
#include "netif/ethernet.h"
#include "lwip/def.h"
#include "lwip/stats.h"
#include "lwip/etharp.h"
#include "lwip/ip.h"
#include "lwip/snmp.h"
#include "lwip/timeouts.h"
//#include "tcpclient.h"
#include "delay.h"
#include "eth_bsp_config.h"


#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

#include "mqttclient.h"
#include "cJSON_Process.h"
#include "core_delay.h"

QueueHandle_t MQTT_Data_Queue = NULL;
#define  MQTT_QUEUE_LEN    4
#define  MQTT_QUEUE_SIZE   4


static TaskHandle_t AppTaskCreate_Handle = NULL;
static TaskHandle_t Test1_Task_Handle = NULL;
static TaskHandle_t Test2_Task_Handle = NULL;


static void AppTaskCreate(void);

static void Test1_Task(void* pvParameters);
static void Test2_Task(void* pvParameters);

extern void TCPIP_Init(void);


extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{
    uint32_t ulReturn;

    ulReturn = taskENTER_CRITICAL_FROM_ISR();

    //HAL_IncTick();
#if (INCLUDE_xTaskGetSchedulerState  == 1 )
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#endif  // INCLUDE_xTaskGetSchedulerState 
        xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState  == 1 )
    }
#endif  // INCLUDE_xTaskGetSchedulerState 


    taskEXIT_CRITICAL_FROM_ISR( ulReturn );
}

extern xSemaphoreHandle s_xSemaphore;
void ETH_RxCpltCallback(void)
{
    //LED2_TOGGLE;
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void ETH_IRQHandler()
{
    uint32_t ulReturn;

    ulReturn = taskENTER_CRITICAL_FROM_ISR();

    if (ETH_GetDMAITStatus(ETH_DMA_IT_R)) {                         // Frame received

        ETH_RxCpltCallback();

        ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
    }
    else if (ETH_GetDMAITStatus(ETH_DMA_IT_T)) {                    // Frame transmitted
        // Transfer complete callback
        // callback

        // Clear the Eth DMA Tx IT pending bits
        ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
    }

    // Clear the interrupt flags
    ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);

    // ETH DMA Error
    if(ETH_GetDMAITStatus(ETH_DMA_FLAG_AIS)) {
        // Ethernet Error callback
        // callback

        // Clear the interrupt flags
        ETH_DMAClearITPendingBit(ETH_DMA_FLAG_AIS);
    }

    taskEXIT_CRITICAL_FROM_ISR( ulReturn );
}


static void AppTaskCreate(void)
{
    BaseType_t xReturn = pdPASS;

    MQTT_Data_Queue = xQueueCreate((UBaseType_t ) MQTT_QUEUE_LEN,
                                   (UBaseType_t ) MQTT_QUEUE_SIZE);
    if(NULL != MQTT_Data_Queue)
        printf("Successfully created MQTT_Data_Queue message queue!\r\n");

    TCPIP_Init();

    mqtt_thread_init();

//  taskENTER_CRITICAL();


    xReturn = xTaskCreate((TaskFunction_t )Test1_Task,
                          (const char*    )"Test1_Task",
                          (uint16_t       )512,
                          (void*          )NULL,
                          (UBaseType_t    )1,
                          (TaskHandle_t*  )&Test1_Task_Handle);
    if(pdPASS == xReturn)
        printf("Create Test1_Task sucess...\r\n");


    xReturn = xTaskCreate((TaskFunction_t )Test2_Task,
                          (const char*    )"Test2_Task",
                          (uint16_t       )512,
                          (void*          )NULL,
                          (UBaseType_t    )2,
                          (TaskHandle_t*  )&Test2_Task_Handle);
    if(pdPASS == xReturn)
        printf("Create Test2_Task sucess...\n\n");

    vTaskDelete(AppTaskCreate_Handle);

    taskEXIT_CRITICAL();
}


static void Test1_Task(void* parameter)
{
    float temp_flag;
    CPU_TS_TmrInit();
    float send_data;

    while (1) {
        temp_flag += 0.1;
        send_data = 3.15 + temp_flag;
        xQueueSend( MQTT_Data_Queue,
                    &send_data,
                    0 );

        vTaskDelay(1000);
    }
}


static void Test2_Task(void* parameter)
{
    while (1) {
        //LED2_TOGGLE;
//    PRINT_DEBUG("LED2_TOGGLE\n");
        vTaskDelay(2000);
    }
}
int main(void)
{
    SystemTick_Count = 0;

    CONSOLE_Init(115200);

    BaseType_t xReturn = pdPASS;


    xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,
                          (const char*    )"AppTaskCreate",
                          (uint16_t       )512,
                          (void*          )NULL,
                          (UBaseType_t    )1,
                          (TaskHandle_t*  )&AppTaskCreate_Handle);

    if(pdPASS == xReturn)
        vTaskStartScheduler();
    else
        return -1;

    while(1);

}



/// @}

/// @}

/// @}
